package com.yiba.vpn.controller;

import com.google.code.kaptcha.Producer;
import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiImplicitParam;
import com.wordnik.swagger.annotations.ApiImplicitParams;
import com.wordnik.swagger.annotations.ApiOperation;
import com.yiba.vpn.authorization.annotation.Authorization;
import com.yiba.vpn.authorization.annotation.CurrentUser;
import com.yiba.vpn.authorization.manager.TokenManager;
import com.yiba.vpn.authorization.model.OauthUserModel;
import com.yiba.vpn.config.Constants;
import com.yiba.vpn.config.ResultStatus;
import com.yiba.vpn.domain.User;
import com.yiba.vpn.dto.UserDto;
import com.yiba.vpn.dto.VcodeDto;
import com.yiba.vpn.dto.WfInfoDto;
import com.yiba.vpn.model.ResultModel;
import com.yiba.vpn.service.InviteService;
import com.yiba.vpn.service.UserService;
import com.yiba.vpn.util.Iputil;
import com.yiba.vpn.util.RegexUtil;

import freemarker.template.TemplateException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 *
 */
@Api(value = "API")
@RestController
@RequestMapping("/user")
public class WfeeUserController {
    private Logger logger = LoggerFactory.getLogger(WfeeUserController.class);

    @Autowired
    private UserService userService;

    @Autowired
    private TokenManager tokenManager;

    @Autowired
    private Producer producer;

    @Autowired
	private InviteService inviteService;

    @Autowired
    private RestTemplate restTemplate;


	@RequestMapping(value = "/do",method = RequestMethod.GET)
    @ApiOperation(value = "执行邀请跳转")
    @ResponseBody
    public ModelAndView doinvite(HttpServletRequest request,ModelAndView mv) {
        String sign = request.getParameter("sign");
        mv = new ModelAndView();
        if(sign != null && RegexUtil.isVpnId(sign)) {
            sign = inviteService.doinvite(sign);
        }
        String uuid = UUID.randomUUID().toString().replace("-", "");
        tokenManager.addV(uuid, uuid, Constants.REGISTER_EXPIRES_SECONDS, TimeUnit.SECONDS);

        tokenManager.addValue(uuid, uuid, Constants.REGISTER_EXPIRES_SECONDS, TimeUnit.SECONDS);
        //  logger.error(uuid+" ；uuid do token =" + tokenManager.getValue(uuid));

        mv.addObject("uuid",uuid);
        mv.addObject("invitationcode", sign);
        mv.setViewName("login");
        return mv;
    }

    @RequestMapping(value = "/invite",method = RequestMethod.GET)
    @ApiOperation(value = "新的邀请跳转")
    @ResponseBody
    public ModelAndView invite(HttpServletRequest request,ModelAndView mv) {
        String sign = request.getParameter("sign");
        String invitecode =null;

       String ipforward = request.getHeader("x-forwarded-for").toString().split(",")[0];
       logger.error("ipforward  >>"+ipforward);
        if(sign ==null || "172.31.26.124".equals(sign) ||"172.31.29.195".equals(sign)){
            logger.error("非邀请分享连接" +request.getRequestURL());
        }else{
            if(sign.startsWith("yq_")) {
                invitecode = RegexUtil.patternNumber(sign);
            }else{
                logger.error("不是正常的分享邀请");
            }
        }

        logger.info("访问的 user/do  host ="+sign+"; invitcode ="+invitecode);

        mv = new ModelAndView();
        if(invitecode != null && RegexUtil.isVpnId(invitecode)) {
            invitecode = inviteService.doinvite(invitecode);
        }
        String uuid = UUID.randomUUID().toString().replace("-", "");
        tokenManager.addV(uuid, uuid, Constants.REGISTER_EXPIRES_SECONDS, TimeUnit.SECONDS);

        tokenManager.addValue(uuid, uuid, Constants.REGISTER_EXPIRES_SECONDS, TimeUnit.SECONDS);
        //  logger.error(uuid+" ；uuid do token =" + tokenManager.getValue(uuid));

        mv.addObject("uuid",uuid);
        mv.addObject("invitationcode", invitecode);
        mv.setViewName("login");
        return mv;
    }


    @RequestMapping(value="/loginweb",method = RequestMethod.POST)
    @ApiOperation(value = "登录接口")
    public ResponseEntity<ResultModel> loginweb(@RequestBody VcodeDto vcodeDto) {
        if(null==vcodeDto || StringUtils.isEmpty(vcodeDto.getEmail()) || StringUtils.isEmpty(vcodeDto.getCode())){
            logger.error(vcodeDto.getEmail()+"邮箱 或者Code为空 >>d登录报错>>Code :"+vcodeDto.getCode());
            return new ResponseEntity<>(ResultModel.error(ResultStatus.REQUEST_PARAMS_ERROR), HttpStatus.OK);
        }

        //校验code 是否正确
        String code = tokenManager.getValue(vcodeDto.getEmail()+"_"+vcodeDto.getCode());
        if (code == null) {
            return new ResponseEntity<>(ResultModel.error(ResultStatus.REQUEST_PARAMS_ERROR), HttpStatus.OK);
        }

        if(!vcodeDto.getCode().equals(code)){
           // logger.error("redis 存的code ="+code+" ; Code 不相同: 传参COde ="+vcodeDto.getCode());
            return new ResponseEntity<>(ResultModel.error(ResultStatus.REQUEST_CODE_VERIFY_ERROR), HttpStatus.OK);
        }else{
            // 删除redis 中的code
            tokenManager.deleteKey(vcodeDto.getEmail()+"_"+vcodeDto.getCode());
        }

        UserDto userDto = new UserDto();
        userDto.setPlatformId(vcodeDto.getEmail());
        userDto.setLoginChannel(8);
        userDto.setUuid(vcodeDto.getUuid());
        OauthUserModel model = this.userService.loginweb(userDto,vcodeDto.getInvitationcode());

        if(null==model){
            return new ResponseEntity<>(ResultModel.error(ResultStatus.INTERNAL_SERVER_ERROR),HttpStatus.OK);
        }
        return new ResponseEntity<>(ResultModel.ok(model), HttpStatus.OK);
    }

    @RequestMapping(value="/wfinfo",method = RequestMethod.POST)
    @ApiOperation(value = "获取wfee信息")
    public ResponseEntity<ResultModel> wfinfo(@RequestBody VcodeDto vcodeDto) {
        WfInfoDto wfInfoDto =userService.queryWfinfo(vcodeDto.getEmail());

        return new ResponseEntity<>(ResultModel.ok(wfInfoDto), HttpStatus.OK);
    }

    @RequestMapping(value="/getvcode",method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "获取邮箱验证码")
    public ResponseEntity<ResultModel> register(HttpServletRequest request,@RequestBody VcodeDto vcodeDto) {


        if(null==vcodeDto || StringUtils.isEmpty(vcodeDto.getEmail())){
            logger.error("获取邮箱验证码 邮箱信息为空！"+vcodeDto.getEmail());
            return new ResponseEntity<>(ResultModel.error(ResultStatus.REQUEST_PARAMS_ERROR), HttpStatus.OK);
        }
        if(StringUtils.isEmpty(vcodeDto.getUuid())   ){
            logger.error("获取邮箱验证码 uuid为空！"+vcodeDto.getEmail());
            return new ResponseEntity<>(ResultModel.error(ResultStatus.REQUEST_AGAIN_ERROR), HttpStatus.OK);
        }

        String xfor = request.getHeader("x-forwarded-for");

        String ipforward = xfor == null ? null : xfor.split(",")[0];

        String ip = ipforward ==null ? Iputil.getRequestIp(request):ipforward;
        if ("172.31.26.124".equals(ip) ||"172.31.29.195".equals(ip)||"0:0:0:0:0:0:0:1".equals(ip) || "127.0.0.1".equals(ip)) {
            ip =null;
        }
        if (!com.yiba.vpn.util.StringUtils.isNullOrEmpty(ip)) {

            if(tokenManager.getValue("BLACK_IP_DISABLE_VIST_RECORD"+ip)!=null){
                logger.error(ipforward+ "; 恶意攻击 ！该IP一分钟内访问发送邮件服务多次  禁止访问 " );
                tokenManager.incr("BLACK_Ip_" + ip,Constants.IP_EXPIRES_SECONDS);
                return new ResponseEntity<>(ResultModel.error(ResultStatus.REQUEST_AGAIN_ERROR), HttpStatus.OK);
            }
            long times =tokenManager.incr("BLACK_Ip_" + ip,Constants.IP_EXPIRES_SECONDS);
            logger.info(ipforward+ "; 该IP一分钟内访问发送邮件服务  >>" +times +" 次 ; 邮箱是 " +vcodeDto.getEmail() );
            if(times >2){
                logger.error(ipforward+ "; 恶意攻击 ！该IP一分钟内访问发送邮件服务  >>" +times +" 次" );
                //记下该请求的IP BLACK_IP_DISABLE_VIST_RECORD
                tokenManager.addV("BLACK_IP_DISABLE_VIST_RECORD"+ip,ip, Constants.BLACK_IP_DISABLE_VIST_RECORD, TimeUnit.SECONDS);

                return new ResponseEntity<>(ResultModel.error(ResultStatus.REQUEST_AGAIN_ERROR), HttpStatus.OK);
            }
        } else {
            logger.error(ipforward+ "Ip 不正常   >>; 邮箱是 " +vcodeDto.getEmail() +" 次" );
        }


        String value = tokenManager.getValue(vcodeDto.getUuid());
        if(value!=null && value.equals(vcodeDto.getUuid()) ){
            String txt = producer.createText();
            vcodeDto.setCode(txt);
            logger.info("发送邮箱请求————"+vcodeDto.getEmail()+";验证码是 ："+txt);
            //删除UUID
            tokenManager.deleteKey(vcodeDto.getUuid()+"");
            return     userService.sendVcodeEmail(vcodeDto);
        }else{
            //删除UUID 在redis 中的存储
            logger.error(value+" <<UUID 在redis 中的存储 UUID 不一样 :"+vcodeDto.getUuid()+">>邮箱是 ："+vcodeDto.getEmail());
           //
        }
        return new ResponseEntity<>(ResultModel.error(ResultStatus.CODE_EXPIRED), HttpStatus.OK);
    }




    //发送邮件Test
    @RequestMapping(value="/sendemail",method = RequestMethod.GET)
    @ApiOperation(value = "发送邮件")
    public ResponseEntity<ResultModel> sendemail(String email,Integer emailtype) {
        if(null==email || StringUtils.isEmpty(email) ||"".equals(email)){
            return new ResponseEntity<>(ResultModel.error(ResultStatus.REQUEST_PARAMS_ERROR), HttpStatus.OK);
        }
        Map<String, String> pp = new HashMap<>();
        try {
            pp = userService.sendemailbyemailtype(email,emailtype);
        } catch (IOException e) {
            pp.put("message",e.getMessage());

        } catch (TemplateException te) {
            pp.put("message",te.getMessage());
        }

        return new ResponseEntity<>(ResultModel.ok(pp), HttpStatus.OK);
    }

    @RequestMapping(value="/lgin",method = RequestMethod.GET)
    @ApiOperation(value = "登录页面")
    public ModelAndView lgin(HttpServletRequest request,ModelAndView mv) {
        String uuid = UUID.randomUUID().toString().replace("-", "");
        tokenManager.addValue(uuid, uuid, Constants.REGISTER_EXPIRES_SECONDS, TimeUnit.SECONDS);
        logger.error(uuid+" ；uuid token =" + tokenManager.getValue(uuid));
        mv = new ModelAndView();
        mv.addObject("uuid",uuid);
        //正常访问 为空
        mv.addObject("invitationcode","");
        mv.setViewName("login");
        return mv;

    }


    @RequestMapping(value = "/logout",method = RequestMethod.DELETE)
    @Authorization
    @ApiOperation(value = "退出登录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "authorization", value = "authorization", required = true, dataType = "string", paramType = "header"),
    })
    public ResponseEntity<ResultModel> logout(@CurrentUser User user) {
        tokenManager.deleteKey(user.getAccount());
        tokenManager.deleteKey(Constants.REFRESH_REDIS_VPN_PREFIX+user.getId());
        return new ResponseEntity<>(ResultModel.ok(), HttpStatus.OK);
    }


}
